#include <stdio.h>
#include <string.h>
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <arpa/inet.h>

#include <cstdio>
#include <cstring>
#include <iostream>
#include "md5.h"
#include "regFetion.h"

using namespace std;


int sendAMsg(int c, char * from , char * to , char * msg ){
    char buf[1024];
	fprintf(stderr,"by socket %d , from %s  to  %s  , the msg is: %s" ,c , from , to , msg);
    memset(buf, 0, 1024);
    
    sprintf(buf, "\
M fetion.com.cn SIP-C/2.0\r\n\
F: %s\r\n\
I: 3\r\n\
Q: 2 M\r\n\
T: sip:%s@fetion.com.cn;p=4020\r\n\
N: SendCatSMS\r\n\
L: %d\r\n\r\n\
%s", from, to, strlen(msg), msg);
/* p equals the first 6 bits of the reciver's cell phone number slash 134099 */

    fprintf(stderr, "SEND:\n%s\n", buf);
    send(c, buf, strlen(buf), 0);
     
    memset(buf, 0, 1024);
    recv(c, buf, 1024, 0);
    fprintf(stderr, "\nRECV:\n%s\n",buf);
    return 0;
}

int createSocket(){
	int c;
	 struct sockaddr_in serveraddr, clientaddr; //the sever and the client.
    socklen_t socklen = sizeof(serveraddr); //   
     
    /* create a socket */
    if ( (c = socket(AF_INET, SOCK_STREAM, 0) ) < 0 ) {
        fprintf(stderr, "create socket error.\n");
        exit( 1 );
    }
    
    /* setup client */
    bzero(&clientaddr,sizeof(clientaddr));
    clientaddr.sin_family = AF_INET;
    /*clientaddr.sin_port = htons(CLIENT_PORT);*/
    clientaddr.sin_addr.s_addr = htons(INADDR_ANY);
    
    /* setup server */
    bzero(&serveraddr,sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    inet_aton(SERVER_HOST, &serveraddr.sin_addr);
    serveraddr.sin_port = htons(SERVER_PORT);
    serveraddr.sin_addr.s_addr = inet_addr(SERVER_HOST);
    
    if ( bind(c, (struct sockaddr*)&clientaddr, sizeof(clientaddr) ) < 0 )
    {
        printf("bind to port failure!\n");
        exit(1);
    }
    
    if ( connect(c, (struct sockaddr*)&serveraddr, socklen) < 0)
    {
        printf("can't connect to %s!\n", SERVER_HOST);
        exit(1);
    }
	return c;

}

int registeration(char *fetionno ,char *pwd )
{

    int rtn_flag = -1 ; /* stands for whether the registeration is OK. */
   
    char cnonce[]="7036EA07568EFC4D6D59FD76141062FE";


    /*/start to create socket -----step 1 -----------------*/
    
    char buf[1024];
    memset(buf, 0, 1024);
    char nonce[33];
    memset(nonce, 0, 33);
    
  	int c=createSocket();//if create is OK,c >= 0  
  	
    sprintf(buf, "\
R fetion.com.cn SIP-C/2.0\r\n\
F: %s\r\nI: 1\r\n\
Q: 1 R\r\nL: 249\r\n\r\n\
<args>\
<device type=\"PC\" version=\"5\" client-version=\"2.3.0210\" />\
<caps value=\"simple-im;im-session;temp-group\" />\
<events value=\"contact;permission;system-message\" />\
<user-info attributes=\"all\" />\
<presence>\
<basic value=\"0\" desc=\"\" />\
</presence>\
</args>", fetionno);
                  
    fprintf(stderr, "\nSEND:\n%s\n",buf);
    send(c, buf, strlen(buf), 0);
     
    memset(buf, 0, 1024);
    recv(c, buf, 1024, 0);
    fprintf(stderr, "\nRECV:\n%s\n",buf);
     
    snprintf(nonce, 33, &(buf[90]));
    fprintf(stderr, "\nNONCE:\n%s\n", nonce);
     
    char *key;
    char *h1;
    char *h2;
    char *response;
    
    memset(buf, 0, 1024);
    memcpy(buf, fetionno, strlen(fetionno));
    memcpy(&(buf[strlen(fetionno)]), ":fetion.com.cn:", 15);
    memcpy(&(buf[strlen(fetionno) + 15]), pwd, strlen(pwd));
    fprintf(stderr, "sid+\":fetion.com.cn:\"+password:\n%s\n", buf);
    md5(buf, &key);
    fprintf(stderr, "key:\n%s\n", key);
    
    memset(buf, 0, 1024);
    memcpy(buf, key, 16);
    memcpy(&(buf[16]), ":", 1);
    memcpy(&(buf[17]), nonce, 33);
    memcpy(&(buf[49]), ":", 1);
    memcpy(&(buf[50]), cnonce, 33);
    fprintf(stderr, "key+':'+nonce+':'+cnonce:\n%s\n", buf);
    md5String(buf, &h1);
    fprintf(stderr, "H1:\n%s\n", h1);
    
    memset(buf, 0, 1024);
    memcpy(buf, "REGISTER:", 9);
    memcpy(&(buf[9]), fetionno, strlen(fetionno));
    fprintf(stderr, "\"REGISTER:\"+sid:\n%s\n", buf);
    md5String(buf, &h2);
    fprintf(stderr, "H2:\n%s\n", h2);
    
    memset(buf, 0, 1024);
    memcpy(buf, h1, 32);
    memcpy(&(buf[32]), ":", 1);
    memcpy(&(buf[33]), nonce, 33);
    memcpy(&(buf[65]), ":", 1);
    memcpy(&(buf[66]), h2, 32);
    fprintf(stderr, "H1+':'+nonce+':'+H2:\n%s\n", buf);
    md5String(buf, &response);
    fprintf(stderr, "response:\n%s\n", response);
    
    memset(buf, 0, 1024);
    sprintf(buf, "\
R fetion.com.cn SIP-C/2.0\r\n\
F: %s\r\n\
I: 1\r\n\
Q: 2 R\r\n\
A: Digest response=\"%s\",cnonce=\"%s\"\r\n\
L: 249\r\n\r\n\
<args>\
<device type=\"PC\" version=\"5\" client-version=\"2.3.0210\" />\
<caps value=\"simple-im;im-session;temp-group\" />\
<events value=\"contact;permission;system-message\" />\
<user-info attributes=\"all\" />\
<presence>\
<basic value=\"0\" desc=\"\" />\
</presence>\
</args>", fetionno, response, cnonce);

    fprintf(stderr, "SEND:\n%s\n", buf);
    send(c, buf, strlen(buf), 0);
     
    memset(buf, 0, 1024);
    recv(c, buf, 1024, 0);
    fprintf(stderr, "\nRECV:\n%s\n",buf);
    
    /*if recv 200 OK from the server then the registeration is success.
    then set the flag to be true.*/
    if(buf[10] == '2' && buf[11]== '0' && buf[12]=='0')
        rtn_flag = c ;
    
    memset(buf, 0, 1024);
 
    return rtn_flag;
}

int closeSocket( int c){
    close(c);
    return 0;
}

char * getMsg(int c){
    char buf[1024];
    memset(buf, 0, 1024);
    recv(c, buf, 1024, 0);
    fprintf(stderr, "\nRECV:\n%s\n",buf);
    return strdup(buf);
}
char * getUserInfo(int c ,char * FetionNo ){ 
    char buf[1024];
    memset(buf, 0, 1024);
    char msg[]="<args>\
                <personal version=\"11\" attributes=\"all\" />\
                <services version=\"11\" attributes=\"all\" />\
                <config version=\"109\" attributes=\"all\" />\
                <mobile-device attributes=\"all\" />\
                </args>";
    sprintf(buf, "\
S fetion.com.cn SIP-C/2.0\r\n\
F: %s\r\n\
I: 5\r\n\
Q: 2 M\r\n\
N: GetPersonalInfo\r\n\
L: %d\r\n\r\n\
%s", FetionNo, strlen(msg), msg);
/* p equals the first 6 bits of the reciver's cell phone number slash 134099 */

    fprintf(stderr, "SEND:\n%s\n", buf);
    send(c, buf, strlen(buf), 0);
     
    memset(buf, 0, 1024);
    recv(c, buf, 1024, 0);
    fprintf(stderr, "\nRECV:\n%s\n",buf);
    return strdup(buf);//ok now.

}
